package com.shk.aop;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.shk.annotation.TableSubmit;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;
@Component
@Aspect
public class Aop002TableSubmit {

    private static final Cache<String,Object> CACHES= CacheBuilder.newBuilder()
            .maximumSize(100) // 设置最大缓存
            .expireAfterAccess(5, TimeUnit.SECONDS) // 设置缓存过期时间
            .build();

    @Pointcut("@annotation(com.shk.annotation.TableSubmit)")
    public void pc(){}


    @Around("pc()")
    public Object  submitCheck(ProceedingJoinPoint pjp) throws Throwable {
        UserDetails principal = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String username = principal.getUsername();


        String tocken=username;
        // 获得表单提交方法的注解
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        TableSubmit submit = signature.getMethod().getAnnotation(TableSubmit.class);
        String key = submit.key();
        // 生成这个用户提交这个表单在内存中唯一的key
        String cacheKey=key+tocken;
        Object proceed=null;
        Object present = CACHES.getIfPresent(cacheKey);
        if(!StringUtils.isEmpty(CACHES.getIfPresent(cacheKey))){
            // 在内存中存在不让提交
            throw new RuntimeException("请勿重复提交");
        }else {
            // 执行提交操作
           proceed = pjp.proceed();
           // 把key保存在cache里面
            CACHES.put(cacheKey,cacheKey);
        }
        System.out.println("拦截到通知");
        System.out.println(CACHES.asMap());
        return proceed;
    }

}
